package com.training.admin.service.impl;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.DataFormatter;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import com.demo2do.core.entity.exception.BusinessException;
import com.demo2do.core.persistence.GenericDaoSupport;
import com.demo2do.core.persistence.annotation.Dao;
import com.demo2do.core.utils.CollectionUtils;
import com.demo2do.core.utils.JsonUtils;
import com.training.admin.dao.TraineeDao;
import com.training.admin.dao.TrainingResultDao;
import com.training.admin.entity.project.ProjectPhase;
import com.training.admin.entity.project.TrainingResult;
import com.training.admin.entity.trainee.Trainee;
import com.training.admin.handler.FileHandler;
import com.training.admin.handler.support.FileStorage;
import com.training.admin.service.ProjectPhaseService;
import com.training.admin.service.ProjectResultService;
import com.training.admin.service.TraineeService;

/**
 * 
 * @author sjh
 *
 */
@Service("projectResultService")
public class ProjectResultServiceImpl implements ProjectResultService {

    private static final Logger logger = LoggerFactory.getLogger(ProjectResultServiceImpl.class);

    @Autowired
    private FileHandler fileHandler;

    @Dao
    private TraineeDao traineeDao;

    @Dao
    private TrainingResultDao trainingResultDao;

    @Autowired
    private GenericDaoSupport genericDaoSupport;

    @Autowired
    private TraineeService traineeService;

    @Autowired
    private ProjectPhaseService projectPhaseService;

    private List<TrainingResult> parse(MultipartFile file) {

        List<TrainingResult> trainingResults = new ArrayList<TrainingResult>();

        DataFormatter dataFormatter = new DataFormatter();
        try {

            Workbook workbook = WorkbookFactory.create(file.getInputStream());

            Sheet sheet = workbook.getSheetAt(0);

            Iterator<Row> rows = sheet.iterator();

            while (rows.hasNext()) {
                
                Row row = rows.next();
                
                int rowNum = row.getRowNum();
                
                logger.info("get current row [{}]", row.getRowNum());

                if (rowNum < 2) {
                    continue;
                }

                String email = dataFormatter.formatCellValue(row.getCell(1)); // 邮箱
                
                logger.info("get email [{}]", email);

                if (StringUtils.isBlank(email)) { // 判断Excel为空行的情况
                    continue;
                }

                String score = dataFormatter.formatCellValue(row.getCell(2)); // 成绩
//                if (StringUtils.isBlank(score)) {
//                    continue;
//                }
                
                logger.info("get score [{}]", score);

                String absence = dataFormatter.formatCellValue(row.getCell(3)); // 缺勤天数
                
                logger.info("get absence [{}]", absence);

                String resit = dataFormatter.formatCellValue(row.getCell(4)); // 是否补考

                String comment = dataFormatter.formatCellValue(row.getCell(5)); // 备注
                TrainingResult trainingResult =
                        new TrainingResult(email, score, absence, resit, comment);

                trainingResults.add(trainingResult);
            }

        } catch (Exception e) {
            logger.error("#parse() - Finishing parsing file with errors.", e);
        }
        return trainingResults;

    }



    /*
     * (non-Javadoc)
     * 
     * @see com.training.admin.service.ProjectResultService#createByFile(org.springframework.web.
     * multipart.MultipartFile)
     */
    @SuppressWarnings("unchecked")
    public void createByFile(MultipartFile file, Long projectPhaseId) {

        try {

            FileStorage fileStorage =
                    new FileStorage("project-result/upload", "project-result-upload",
                            FilenameUtils.getExtension(file.getOriginalFilename()));
            fileHandler.save(fileStorage, file.getInputStream());

            List<TrainingResult> trainingResults = this.parse(file);
            logger.info("get result [{}]", JsonUtils.toJson(trainingResults));

            ProjectPhase projectPhase =
                    projectPhaseService.load(ProjectPhase.class, projectPhaseId);

            List<String> emails =
CollectionUtils.extractPropertyList(trainingResults, "trainee.email");
            List<Trainee> trainees = traineeDao.listByEmails(emails);

            Map<String, Trainee> traineesMap = CollectionUtils.constructMapValue(trainees, "email");

            List<TrainingResult> exitTrainingResults =
                    trainingResultDao.loadByTraineeAndProject(emails, projectPhaseId);
            Map<String, TrainingResult> exitTrainingResultsMap =
                    CollectionUtils.constructMapValue(exitTrainingResults, "trainee.email");

            for (TrainingResult trainingResult : trainingResults) {

                TrainingResult exittrainingResult =
                        exitTrainingResultsMap.get(trainingResult.getTrainee().getEmail());
                Trainee trainee = traineesMap.get(trainingResult.getTrainee().getEmail());

                if (trainee == null) {
                    logger.error("trainee [{}] is not exit",
                            trainingResult.getTrainee().getEmail());
                    continue;
                }

                if (exittrainingResult != null) {
                    genericDaoSupport.update(exittrainingResult.upload(trainingResult.getScore(),
                            trainingResult.getAbsence(), trainingResult.isResit(),
                            trainingResult.getComment()));
                } else {
                    TrainingResult addTrainingResult =
                            new TrainingResult(projectPhase, trainingResult, trainee);
                    genericDaoSupport.save(addTrainingResult);
                }
            }
        } catch (Exception e) {
            logger.error("#upload() - batch upload driver fail, exception is [{}]", e);
            throw BusinessException.newInstance("500", "批量上传失败，" + e.getMessage());
        }
    }



    /*
     * (non-Javadoc)
     * 
     * @see com.training.admin.service.ProjectResultService#inputResult(java.lang.String[],
     * java.lang.String[], java.lang.String[], java.lang.String[], java.lang.String[])
     */
    public void inputResult(Long projectPhaseId, Long userId, Float score, String comment,
            Float absence, Boolean resit) {


        ProjectPhase projectPhase = projectPhaseService.load(ProjectPhase.class, projectPhaseId);

        TrainingResult trainingResult =
                trainingResultDao.loadByTraineeAndProjectPhase(userId, projectPhaseId);
        if (trainingResult != null) {
            trainingResult.upload(score, absence, resit, comment);
            genericDaoSupport.update(trainingResult);

        } else {
            Trainee trainee = traineeService.load(Trainee.class, userId);
            TrainingResult trainingResult2 =
                    new TrainingResult(trainee, score, absence, resit, comment);
            genericDaoSupport.save(trainingResult2.inputResult(projectPhase));

        }
    }

}
